Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 349
0.00% covered (danger)
0.00%
0 / 147
0.00% covered (danger)
0.00%
0 / 3274
0.00% covered (danger)
0.00%
0 / 18
CRAP
0.00% covered (danger)
0.00%
0 / 1
Repository
0.00% covered (danger)
0.00%
0 / 349
0.00% covered (danger)
0.00%
0 / 147
0.00% covered (danger)
0.00%
0 / 3274
0.00% covered (danger)
0.00%
0 / 18
7832
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 newDataObject
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 exists
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 get
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCollector
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSchemaMap
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getIdsBySetting
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDateBoundaries
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 validate
0.00% covered (danger)
0.00%
0 / 60
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
342
 validatePublish
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 52
0.00% covered (danger)
0.00%
0 / 1
90
 add
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
42
 version
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 40
0.00% covered (danger)
0.00%
0 / 1
56
 edit
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
30
 publish
0.00% covered (danger)
0.00%
0 / 67
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 3072
0.00% covered (danger)
0.00%
0 / 1
182
 setStatusOnPublish
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
0
 unpublish
0.00% covered (danger)
0.00%
0 / 44
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
30
 delete
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 _saveFileParam
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
182
 getErrorMessageOverrides
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 createDois
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
0
1<?php
2/**
3 * @file classes/publication/Repository.php
4 *
5 * Copyright (c) 2014-2020 Simon Fraser University
6 * Copyright (c) 2000-2020 John Willinsky
7 * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
8 *
9 * @class Repository
10 *
11 * @brief A repository to find and manage publications.
12 */
13
14namespace PKP\publication;
15
16use APP\core\Application;
17use APP\core\Request;
18use APP\facades\Repo;
19use APP\file\PublicFileManager;
20use APP\publication\DAO;
21use APP\publication\Publication;
22use APP\submission\Submission;
23use Illuminate\Support\Enumerable;
24use Illuminate\Support\LazyCollection;
25use PKP\context\Context;
26use PKP\core\Core;
27use PKP\core\PKPApplication;
28use PKP\db\DAORegistry;
29use PKP\file\TemporaryFileManager;
30use PKP\log\event\PKPSubmissionEventLogEntry;
31use PKP\observers\events\PublicationPublished;
32use PKP\observers\events\PublicationUnpublished;
33use PKP\orcid\OrcidManager;
34use PKP\plugins\Hook;
35use PKP\security\Validation;
36use PKP\services\PKPSchemaService;
37use PKP\submission\Genre;
38use PKP\submission\PKPSubmission;
39use PKP\userGroup\UserGroup;
40use PKP\validation\ValidatorFactory;
41
42abstract class Repository
43{
44    /** @var DAO */
45    public $dao;
46
47    /** @var string $schemaMap The name of the class to map this entity to its schema */
48    public $schemaMap = maps\Schema::class;
49
50    /** @var Request */
51    protected $request;
52
53    /** @var PKPSchemaService<Publication> */
54    protected $schemaService;
55
56    public function __construct(DAO $dao, Request $request, PKPSchemaService $schemaService)
57    {
58        $this->dao = $dao;
59        $this->request = $request;
60        $this->schemaService = $schemaService;
61    }
62
63    /** @copydoc DAO::newDataObject() */
64    public function newDataObject(array $params = []): Publication
65    {
66        $object = $this->dao->newDataObject();
67        if (!empty($params)) {
68            $object->setAllData($params);
69        }
70        return $object;
71    }
72
73    /** @copydoc DAO::exists() */
74    public function exists(int $id, ?int $submissionId = null): bool
75    {
76        return $this->dao->exists($id, $submissionId);
77    }
78
79    /** @copydoc DAO::get() */
80    public function get(int $id, ?int $submissionId = null): ?Publication
81    {
82        return $this->dao->get($id, $submissionId);
83    }
84
85    /** @copydoc DAO::getCollector() */
86    public function getCollector(): Collector
87    {
88        return app(Collector::class);
89    }
90
91    /**
92     * Get an instance of the map class for mapping
93     * publications to their schema
94     *
95     * @param LazyCollection<int,UserGroup> $userGroups
96     * @param Genre[] $genres
97     */
98    public function getSchemaMap(Submission $submission, LazyCollection $userGroups, array $genres): maps\Schema
99    {
100        return app('maps')->withExtensions(
101            $this->schemaMap,
102            [
103                'submission' => $submission,
104                'userGroups' => $userGroups,
105                'genres' => $genres,
106            ]
107        );
108    }
109
110    /** @copydoc DAO:: getIdsBySetting()*/
111    public function getIdsBySetting(string $settingName, $settingValue, int $contextId): Enumerable
112    {
113        return $this->dao->getIdsBySetting($settingName, $settingValue, $contextId);
114    }
115
116    /** @copydoc DAO:: getDateBoundaries()*/
117    public function getDateBoundaries(Collector $query): object
118    {
119        return $this->dao->getDateBoundaries($query);
120    }
121
122    /**
123     * Validate properties for a publication
124     *
125     * Perform validation checks on data used to add or edit a publication.
126     *
127     * @param Publication|null $publication The publication being edited. Pass `null` if creating a new publication
128     * @param array $props A key/value array with the new data to validate
129     *
130     * @return array A key/value array with validation errors. Empty if no errors
131     *
132     * @hook Publication::validate [[&$errors, $publication, $props, $allowedLocales, $primaryLocale]]
133     */
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
233
234    /**
235     * Validate a publication against publishing requirements
236     *
237     * This validation check should return zero errors before
238     * publishing a publication.
239     *
240     * It should not be necessary to repeat validation rules from
241     * self::validate(). These rules should be applied during all add
242     * or edit actions.
243     *
244     * This additional check should be used when a journal or press
245     * wants to enforce particular publishing requirements, such as
246     * requiring certain metadata or other information.
247     *
248     * @param array $allowedLocales The context's supported submission metadata locales
249     * @param string $primaryLocale The submission's primary locale
250     *
251     * @hook Publication::validatePublish [[&$errors, $publication, $submission, $allowedLocales, $primaryLocale]]
252     */
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
286
287    /** @copydoc DAO::insert() */
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
301                $submissionContext = app()->get('context')->get($submission->getData('contextId'));
302            }
303
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
322
323    /**
324     * Create a new version of a publication
325     *
326     * Makes a copy of an existing publication, without the datePublished,
327     * and makes copies of all associated objects.
328     *
329     * @hook Publication::version [[&$newPublication, $publication]]
330     */
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
398
399    /** @copydoc DAO::update() */
400    public function edit(Publication $publication, array $params): Publication
401    {
402        $submission = Repo::submission()->get($publication->getData('submissionId'));
403        $userId = $this->request->getUser()?->getId();
404
405        // Move uploaded files into place and update the params
406        if (array_key_exists('coverImage', $params)) {
407            $submissionContext = $this->request->getContext();
408            if ($submissionContext->getId() !== $submission->getData('contextId')) {
409                $submissionContext = app()->get('context')->get($submission->getData('contextId'));
410            }
411
412            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
413            foreach ($supportedLocales as $localeKey) {
414                if (!array_key_exists($localeKey, $params['coverImage'])) {
415                    continue;
416                }
417                $params['coverImage'][$localeKey] = $this->_saveFileParam($publication, $submission, $params['coverImage'][$localeKey], 'coverImage', $userId, $localeKey, true);
418            }
419        }
420
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
422        $newPublication->stampModified();
423
424        Hook::call('Publication::edit', [&$newPublication, $publication, $params, $this->request]);
425
426        $this->dao->update($newPublication, $publication);
427
428        $newPublication = Repo::publication()->get($newPublication->getId());
429
430        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
431
432        // Log an event when publication data is updated
433        $eventLog = Repo::eventLog()->newDataObject([
434            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
435            'assocId' => $submission->getId(),
436            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UPDATE,
437            'userId' => Validation::loggedInAs() ?? $userId,
438            'message' => 'submission.event.general.metadataUpdated',
439            'isTranslated' => false,
440            'dateLogged' => Core::getCurrentDate(),
441        ]);
442        Repo::eventLog()->add($eventLog);
443
444        return $newPublication;
445    }
446
447    /**
448     * Publish a publication
449     *
450     * This method performs all actions needed when publishing an item, such
451     * as setting metadata, logging events, updating the search index, etc.
452     *
453     * @throws \Exception
454     *
455     * @see self::setStatusOnPublish()
456     *
457     * @hook Publication::publish::before [[&$newPublication, $publication]]
458     */
459    public function publish(Publication $publication)
460    {
461        $newPublication = clone $publication;
462        $newPublication->stampModified();
463
464        $this->setStatusOnPublish($newPublication);
465
466        // Set the copyright and license information
467        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
468
469        $itsPublished = ($newPublication->getData('status') === PKPSubmission::STATUS_PUBLISHED);
470
471        if ($itsPublished && !$newPublication->getData('copyrightHolder')) {
472            $newPublication->setData(
473                'copyrightHolder',
474                $submission->_getContextLicenseFieldValue(
475                    null,
476                    PKPSubmission::PERMISSIONS_FIELD_COPYRIGHT_HOLDER,
477                    $newPublication
478                )
479            );
480        }
481
482        if ($itsPublished && !$newPublication->getData('copyrightYear')) {
483            $newPublication->setData(
484                'copyrightYear',
485                $submission->_getContextLicenseFieldValue(
486                    null,
487                    PKPSubmission::PERMISSIONS_FIELD_COPYRIGHT_YEAR,
488                    $newPublication
489                )
490            );
491        }
492
493        if ($itsPublished && !$newPublication->getData('licenseUrl')) {
494            $newPublication->setData(
495                'licenseUrl',
496                $submission->_getContextLicenseFieldValue(
497                    null,
498                    PKPSubmission::PERMISSIONS_FIELD_LICENSE_URL,
499                    $newPublication
500                )
501            );
502        }
503
504        Hook::call('Publication::publish::before', [&$newPublication, $publication]);
505
506        $this->dao->update($newPublication);
507
508        $newPublication = Repo::publication()->get($newPublication->getId());
509        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
510
511        // Update a submission's status based on the status of its publications
512        if ($newPublication->getData('status') !== $publication->getData('status')) {
513            Repo::submission()->updateStatus($submission);
514            $submission = Repo::submission()->get($submission->getId());
515        }
516
517        $msg = ($newPublication->getData('status') === Submission::STATUS_SCHEDULED) ? 'publication.event.scheduled' : 'publication.event.published';
518
519        // Log an event when publication is published. Adjust the message depending
520        // on whether this is the first publication or a subsequent version
521        if (count($submission->getData('publications')) > 1) {
522            $msg = ($newPublication->getData('status') === Submission::STATUS_SCHEDULED) ? 'publication.event.versionScheduled' : 'publication.event.versionPublished';
523        }
524
525        $eventLog = Repo::eventLog()->newDataObject([
526            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
527            'assocId' => $submission->getId(),
528            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_PUBLISH,
529            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
530            'message' => $msg,
531            'isTranslated' => false,
532            'dateLogged' => Core::getCurrentDate()
533        ]);
534        Repo::eventLog()->add($eventLog);
535
536        // Mark DOIs stale (if applicable).
537        if ($newPublication->getData('status') === Submission::STATUS_PUBLISHED) {
538            $staleDoiIds = Repo::doi()->getDoisForSubmission($newPublication->getData('submissionId'));
539            Repo::doi()->markStale($staleDoiIds);
540        }
541
542        Hook::call(
543            'Publication::publish',
544            [
545                &$newPublication,
546                $publication,
547                $submission
548            ]
549        );
550
551        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()?->getId()
552            ? Application::get()->getRequest()->getContext()
553            : app()->get('context')->get($submission->getData('contextId'));
554
555        event(new PublicationPublished($newPublication, $publication, $submission, $context));
556    }
557
558    /**
559     * Set the status when an item is published
560     *
561     * Each application may handle publishing in a different way. Implement this method
562     * in an app-specific child class by assigning `status` and `datePublished` for this
563     * publication.
564     *
565     * This method should be called by self::publish().
566     *
567     * @hook Publication::unpublish::before [[ &$newPublication, $publication ]]
568     */
569    abstract protected function setStatusOnPublish(Publication $publication);
570
571    /**
572     * Unpublish a publication
573     *
574     * This method performs all actions needed when unpublishing an item, such
575     * as changing the status, logging events, updating the search index, etc.
576     *
577     * @see self::setStatusOnPublish()
578     *
579     * @hook Publication::unpublish::before [[ &$newPublication, $publication ]]
580     */
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
602            Repo::submission()->updateStatus($submission);
603            $submission = Repo::submission()->get($submission->getId());
604        }
605
606        // Log an event when publication is unpublished. Adjust the message depending
607        // on whether this is the first publication or a subsequent version
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
611            $msg = 'publication.event.versionUnpublished';
612        }
613
614        // Mark DOIs stable (if applicable).
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
616            $staleDoiIds = Repo::doi()->getDoisForSubmission($newPublication->getData('submissionId'));
617            Repo::doi()->markStale($staleDoiIds);
618        }
619
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
646
647    /** @copydoc DAO::delete() */
648    public function delete(Publication $publication)
649    {
650        Hook::call('Publication::delete::before', [&$publication]);
651
652        $submission = Repo::submission()->get($publication->getData('submissionId'));
653        $sectionId = $publication->getData(Application::getSectionIdPropName());
654        $section = $sectionId ? Repo::section()->get($sectionId) : null;
655
656        $this->dao->delete($publication);
657
658        // Update a submission's status based on the status of its remaining publications
659        $submission = Repo::submission()->get($publication->getData('submissionId'));
660        Repo::submission()->updateStatus($submission, null, $section);
661
662        Hook::call('Publication::delete', [&$publication]);
663    }
664
665    /**
666     * Handle a publication setting for an uploaded file
667     *
668     * - Moves the temporary file to the public directory
669     * - Resets the param value to what is expected to be stored in the db
670     * - If a null value is passed, deletes any existing file
671     *
672     * This method is protected because all operations which edit publications should
673     * go through the add and edit methods in order to ensure that
674     * the appropriate hooks are fired.
675     *
676     * @param Publication $publication The publication being edited
677     * @param Submission $submission The submission this publication is part of
678     * @param mixed $value The param value to be saved. Contains the temporary
679     *  file ID if a new file has been uploaded.
680     * @param string $settingName The name of the setting to save, typically used
681     *  in the filename.
682     * @param int $userId ID of the user who owns the temporary file
683     * @param string $localeKey Optional. Pass if the setting is multilingual
684     * @param bool $isImage Optional. For image files which include alt text in value
685     *
686     * @return string|array|bool New param value or false on failure
687     */
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
699            $oldPublication = Repo::publication()->get($publication->getId());
700            $oldValue = $oldPublication->getData($settingName, $localeKey);
701            $fileName = $oldValue['uploadName'] ?? null;
702            if ($fileName) {
703                // File may be in use by other publications
704                $fileInUse = false;
705                foreach ($submission->getData('publications') as $iPublication) {
706                    if ($publication->getId() === $iPublication->getId()) {
707                        continue;
708                    }
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
711                        $fileInUse = true;
712                        continue;
713                    }
714                }
715                if (!$fileInUse) {
716                    $publicFileManager = new PublicFileManager();
717                    $publicFileManager->removeContextFile($submission->getData('contextId'), $fileName);
718                }
719            }
720            return null;
721        }
722
723        // Check if there is something to upload
724        if (empty($value['temporaryFileId'])) {
725            return $value;
726        }
727
728        // Get the submission context
729        $submissionContext = $this->request->getContext();
730        if ($submissionContext->getId() !== $submission->getData('contextId')) {
731            $submissionContext = app()->get('context')->get($submission->getData('contextId'));
732        }
733
734        $temporaryFileManager = new TemporaryFileManager();
735        $temporaryFile = $temporaryFileManager->getFile((int) $value['temporaryFileId'], $userId);
736        $fileNameBase = join('_', ['submission', $submission->getId(), $publication->getId(), $settingName]); // eg - submission_1_1_coverImage
737        $fileName = app()->get('context')->moveTemporaryFile($submissionContext, $temporaryFile, $fileNameBase, $userId, $localeKey);
738
739        if ($fileName) {
740            if ($isImage) {
741                return [
742                    'altText' => !empty($value['altText']) ? $value['altText'] : '',
743                    'dateUploaded' => Core::getCurrentDate(),
744                    'uploadName' => $fileName,
745                ];
746            } else {
747                return [
748                    'dateUploaded' => Core::getCurrentDate(),
749                    'uploadName' => $fileName,
750                ];
751            }
752        }
753
754        return null;
755    }
756
757    /**
758     * Get error message overrides for the validator
759     */
760    protected function getErrorMessageOverrides(): array
761    {
762        return [
763            'locale.regex' => __('validator.localeKey'),
764            'datePublished.date_format' => __('publication.datePublished.errorFormat'),
765            'urlPath.regex' => __('validator.alpha_dash_period'),
766        ];
767    }
768
769    /**
770     * Create all DOIs associated with the publication.
771     */
772    abstract protected function createDois(Publication $newPublication): void;
773}

Paths

Below are the source code lines that represent each code path as identified by Xdebug. Please note a path is not necessarily coterminous with a line, a line may contain multiple paths and therefore show up more than once. Please also be aware that some paths may include implicit rather than explicit branches, e.g. an if statement always has an else as part of its logical flow even if you didn't write one.

PKP\publication\
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
174                    ? $props['title'][$primaryLocale]
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
 
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
 
179            });
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
174                    ? $props['title'][$primaryLocale]
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
 
179            });
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
 
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
 
179            });
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
 
179            });
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
174                    ? $props['title'][$primaryLocale]
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
 
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
 
179            });
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
174                    ? $props['title'][$primaryLocale]
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
 
179            });
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
 
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
 
179            });
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
 
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
 
179            });
Repository->__construct
56    public function __construct(DAO $dao, Request $request, PKPSchemaService $schemaService)
57    {
58        $this->dao = $dao;
59        $this->request = $request;
60        $this->schemaService = $schemaService;
61    }
Repository->_saveFileParam
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
699            $oldPublication = Repo::publication()->get($publication->getId());
700            $oldValue = $oldPublication->getData($settingName, $localeKey);
701            $fileName = $oldValue['uploadName'] ?? null;
702            if ($fileName) {
 
704                $fileInUse = false;
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
706                    if ($publication->getId() === $iPublication->getId()) {
 
707                        continue;
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
706                    if ($publication->getId() === $iPublication->getId()) {
707                        continue;
708                    }
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
711                        $fileInUse = true;
712                        continue;
713                    }
714                }
715                if (!$fileInUse) {
 
716                    $publicFileManager = new PublicFileManager();
717                    $publicFileManager->removeContextFile($submission->getData('contextId'), $fileName);
718                }
719            }
720            return null;
 
720            return null;
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
699            $oldPublication = Repo::publication()->get($publication->getId());
700            $oldValue = $oldPublication->getData($settingName, $localeKey);
701            $fileName = $oldValue['uploadName'] ?? null;
702            if ($fileName) {
 
704                $fileInUse = false;
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
706                    if ($publication->getId() === $iPublication->getId()) {
 
707                        continue;
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
706                    if ($publication->getId() === $iPublication->getId()) {
707                        continue;
708                    }
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
711                        $fileInUse = true;
712                        continue;
713                    }
714                }
715                if (!$fileInUse) {
 
720            return null;
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
699            $oldPublication = Repo::publication()->get($publication->getId());
700            $oldValue = $oldPublication->getData($settingName, $localeKey);
701            $fileName = $oldValue['uploadName'] ?? null;
702            if ($fileName) {
 
704                $fileInUse = false;
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
706                    if ($publication->getId() === $iPublication->getId()) {
 
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
711                        $fileInUse = true;
712                        continue;
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
706                    if ($publication->getId() === $iPublication->getId()) {
707                        continue;
708                    }
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
711                        $fileInUse = true;
712                        continue;
713                    }
714                }
715                if (!$fileInUse) {
 
716                    $publicFileManager = new PublicFileManager();
717                    $publicFileManager->removeContextFile($submission->getData('contextId'), $fileName);
718                }
719            }
720            return null;
 
720            return null;
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
699            $oldPublication = Repo::publication()->get($publication->getId());
700            $oldValue = $oldPublication->getData($settingName, $localeKey);
701            $fileName = $oldValue['uploadName'] ?? null;
702            if ($fileName) {
 
704                $fileInUse = false;
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
706                    if ($publication->getId() === $iPublication->getId()) {
 
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
711                        $fileInUse = true;
712                        continue;
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
706                    if ($publication->getId() === $iPublication->getId()) {
707                        continue;
708                    }
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
711                        $fileInUse = true;
712                        continue;
713                    }
714                }
715                if (!$fileInUse) {
 
720            return null;
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
699            $oldPublication = Repo::publication()->get($publication->getId());
700            $oldValue = $oldPublication->getData($settingName, $localeKey);
701            $fileName = $oldValue['uploadName'] ?? null;
702            if ($fileName) {
 
704                $fileInUse = false;
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
706                    if ($publication->getId() === $iPublication->getId()) {
 
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
706                    if ($publication->getId() === $iPublication->getId()) {
707                        continue;
708                    }
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
711                        $fileInUse = true;
712                        continue;
713                    }
714                }
715                if (!$fileInUse) {
 
716                    $publicFileManager = new PublicFileManager();
717                    $publicFileManager->removeContextFile($submission->getData('contextId'), $fileName);
718                }
719            }
720            return null;
 
720            return null;
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
699            $oldPublication = Repo::publication()->get($publication->getId());
700            $oldValue = $oldPublication->getData($settingName, $localeKey);
701            $fileName = $oldValue['uploadName'] ?? null;
702            if ($fileName) {
 
704                $fileInUse = false;
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
706                    if ($publication->getId() === $iPublication->getId()) {
 
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
706                    if ($publication->getId() === $iPublication->getId()) {
707                        continue;
708                    }
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
711                        $fileInUse = true;
712                        continue;
713                    }
714                }
715                if (!$fileInUse) {
 
720            return null;
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
699            $oldPublication = Repo::publication()->get($publication->getId());
700            $oldValue = $oldPublication->getData($settingName, $localeKey);
701            $fileName = $oldValue['uploadName'] ?? null;
702            if ($fileName) {
 
704                $fileInUse = false;
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
706                    if ($publication->getId() === $iPublication->getId()) {
 
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
711                        $fileInUse = true;
712                        continue;
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
706                    if ($publication->getId() === $iPublication->getId()) {
707                        continue;
708                    }
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
711                        $fileInUse = true;
712                        continue;
713                    }
714                }
715                if (!$fileInUse) {
 
716                    $publicFileManager = new PublicFileManager();
717                    $publicFileManager->removeContextFile($submission->getData('contextId'), $fileName);
718                }
719            }
720            return null;
 
720            return null;
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
699            $oldPublication = Repo::publication()->get($publication->getId());
700            $oldValue = $oldPublication->getData($settingName, $localeKey);
701            $fileName = $oldValue['uploadName'] ?? null;
702            if ($fileName) {
 
704                $fileInUse = false;
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
706                    if ($publication->getId() === $iPublication->getId()) {
 
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
711                        $fileInUse = true;
712                        continue;
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
706                    if ($publication->getId() === $iPublication->getId()) {
707                        continue;
708                    }
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
711                        $fileInUse = true;
712                        continue;
713                    }
714                }
715                if (!$fileInUse) {
 
720            return null;
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
699            $oldPublication = Repo::publication()->get($publication->getId());
700            $oldValue = $oldPublication->getData($settingName, $localeKey);
701            $fileName = $oldValue['uploadName'] ?? null;
702            if ($fileName) {
 
704                $fileInUse = false;
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
706                    if ($publication->getId() === $iPublication->getId()) {
 
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
706                    if ($publication->getId() === $iPublication->getId()) {
707                        continue;
708                    }
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
711                        $fileInUse = true;
712                        continue;
713                    }
714                }
715                if (!$fileInUse) {
 
716                    $publicFileManager = new PublicFileManager();
717                    $publicFileManager->removeContextFile($submission->getData('contextId'), $fileName);
718                }
719            }
720            return null;
 
720            return null;
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
699            $oldPublication = Repo::publication()->get($publication->getId());
700            $oldValue = $oldPublication->getData($settingName, $localeKey);
701            $fileName = $oldValue['uploadName'] ?? null;
702            if ($fileName) {
 
704                $fileInUse = false;
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
706                    if ($publication->getId() === $iPublication->getId()) {
 
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
706                    if ($publication->getId() === $iPublication->getId()) {
707                        continue;
708                    }
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
711                        $fileInUse = true;
712                        continue;
713                    }
714                }
715                if (!$fileInUse) {
 
720            return null;
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
699            $oldPublication = Repo::publication()->get($publication->getId());
700            $oldValue = $oldPublication->getData($settingName, $localeKey);
701            $fileName = $oldValue['uploadName'] ?? null;
702            if ($fileName) {
 
704                $fileInUse = false;
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
706                    if ($publication->getId() === $iPublication->getId()) {
707                        continue;
708                    }
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
711                        $fileInUse = true;
712                        continue;
713                    }
714                }
715                if (!$fileInUse) {
 
716                    $publicFileManager = new PublicFileManager();
717                    $publicFileManager->removeContextFile($submission->getData('contextId'), $fileName);
718                }
719            }
720            return null;
 
720            return null;
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
699            $oldPublication = Repo::publication()->get($publication->getId());
700            $oldValue = $oldPublication->getData($settingName, $localeKey);
701            $fileName = $oldValue['uploadName'] ?? null;
702            if ($fileName) {
 
704                $fileInUse = false;
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
706                    if ($publication->getId() === $iPublication->getId()) {
707                        continue;
708                    }
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
711                        $fileInUse = true;
712                        continue;
713                    }
714                }
715                if (!$fileInUse) {
 
720            return null;
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
699            $oldPublication = Repo::publication()->get($publication->getId());
700            $oldValue = $oldPublication->getData($settingName, $localeKey);
701            $fileName = $oldValue['uploadName'] ?? null;
702            if ($fileName) {
 
704                $fileInUse = false;
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
706                    if ($publication->getId() === $iPublication->getId()) {
707                        continue;
708                    }
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
711                        $fileInUse = true;
712                        continue;
713                    }
714                }
715                if (!$fileInUse) {
 
716                    $publicFileManager = new PublicFileManager();
717                    $publicFileManager->removeContextFile($submission->getData('contextId'), $fileName);
718                }
719            }
720            return null;
 
720            return null;
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
699            $oldPublication = Repo::publication()->get($publication->getId());
700            $oldValue = $oldPublication->getData($settingName, $localeKey);
701            $fileName = $oldValue['uploadName'] ?? null;
702            if ($fileName) {
 
704                $fileInUse = false;
705                foreach ($submission->getData('publications') as $iPublication) {
 
705                foreach ($submission->getData('publications') as $iPublication) {
706                    if ($publication->getId() === $iPublication->getId()) {
707                        continue;
708                    }
709                    $iValue = $iPublication->getData($settingName, $localeKey);
710                    if (!empty($iValue['uploadName']) && $iValue['uploadName'] === $fileName) {
711                        $fileInUse = true;
712                        continue;
713                    }
714                }
715                if (!$fileInUse) {
 
720            return null;
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
699            $oldPublication = Repo::publication()->get($publication->getId());
700            $oldValue = $oldPublication->getData($settingName, $localeKey);
701            $fileName = $oldValue['uploadName'] ?? null;
702            if ($fileName) {
 
720            return null;
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
724        if (empty($value['temporaryFileId'])) {
 
725            return $value;
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
724        if (empty($value['temporaryFileId'])) {
 
729        $submissionContext = $this->request->getContext();
730        if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
731            $submissionContext = app()->get('context')->get($submission->getData('contextId'));
732        }
733
734        $temporaryFileManager = new TemporaryFileManager();
 
734        $temporaryFileManager = new TemporaryFileManager();
735        $temporaryFile = $temporaryFileManager->getFile((int) $value['temporaryFileId'], $userId);
736        $fileNameBase = join('_', ['submission', $submission->getId(), $publication->getId(), $settingName]); // eg - submission_1_1_coverImage
737        $fileName = app()->get('context')->moveTemporaryFile($submissionContext, $temporaryFile, $fileNameBase, $userId, $localeKey);
738
739        if ($fileName) {
 
740            if ($isImage) {
 
742                    'altText' => !empty($value['altText']) ? $value['altText'] : '',
 
742                    'altText' => !empty($value['altText']) ? $value['altText'] : '',
 
742                    'altText' => !empty($value['altText']) ? $value['altText'] : '',
743                    'dateUploaded' => Core::getCurrentDate(),
744                    'uploadName' => $fileName,
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
724        if (empty($value['temporaryFileId'])) {
 
729        $submissionContext = $this->request->getContext();
730        if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
731            $submissionContext = app()->get('context')->get($submission->getData('contextId'));
732        }
733
734        $temporaryFileManager = new TemporaryFileManager();
 
734        $temporaryFileManager = new TemporaryFileManager();
735        $temporaryFile = $temporaryFileManager->getFile((int) $value['temporaryFileId'], $userId);
736        $fileNameBase = join('_', ['submission', $submission->getId(), $publication->getId(), $settingName]); // eg - submission_1_1_coverImage
737        $fileName = app()->get('context')->moveTemporaryFile($submissionContext, $temporaryFile, $fileNameBase, $userId, $localeKey);
738
739        if ($fileName) {
 
740            if ($isImage) {
 
742                    'altText' => !empty($value['altText']) ? $value['altText'] : '',
 
742                    'altText' => !empty($value['altText']) ? $value['altText'] : '',
 
742                    'altText' => !empty($value['altText']) ? $value['altText'] : '',
743                    'dateUploaded' => Core::getCurrentDate(),
744                    'uploadName' => $fileName,
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
724        if (empty($value['temporaryFileId'])) {
 
729        $submissionContext = $this->request->getContext();
730        if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
731            $submissionContext = app()->get('context')->get($submission->getData('contextId'));
732        }
733
734        $temporaryFileManager = new TemporaryFileManager();
 
734        $temporaryFileManager = new TemporaryFileManager();
735        $temporaryFile = $temporaryFileManager->getFile((int) $value['temporaryFileId'], $userId);
736        $fileNameBase = join('_', ['submission', $submission->getId(), $publication->getId(), $settingName]); // eg - submission_1_1_coverImage
737        $fileName = app()->get('context')->moveTemporaryFile($submissionContext, $temporaryFile, $fileNameBase, $userId, $localeKey);
738
739        if ($fileName) {
 
740            if ($isImage) {
 
748                    'dateUploaded' => Core::getCurrentDate(),
749                    'uploadName' => $fileName,
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
724        if (empty($value['temporaryFileId'])) {
 
729        $submissionContext = $this->request->getContext();
730        if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
731            $submissionContext = app()->get('context')->get($submission->getData('contextId'));
732        }
733
734        $temporaryFileManager = new TemporaryFileManager();
 
734        $temporaryFileManager = new TemporaryFileManager();
735        $temporaryFile = $temporaryFileManager->getFile((int) $value['temporaryFileId'], $userId);
736        $fileNameBase = join('_', ['submission', $submission->getId(), $publication->getId(), $settingName]); // eg - submission_1_1_coverImage
737        $fileName = app()->get('context')->moveTemporaryFile($submissionContext, $temporaryFile, $fileNameBase, $userId, $localeKey);
738
739        if ($fileName) {
 
754        return null;
755    }
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
724        if (empty($value['temporaryFileId'])) {
 
729        $submissionContext = $this->request->getContext();
730        if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
734        $temporaryFileManager = new TemporaryFileManager();
735        $temporaryFile = $temporaryFileManager->getFile((int) $value['temporaryFileId'], $userId);
736        $fileNameBase = join('_', ['submission', $submission->getId(), $publication->getId(), $settingName]); // eg - submission_1_1_coverImage
737        $fileName = app()->get('context')->moveTemporaryFile($submissionContext, $temporaryFile, $fileNameBase, $userId, $localeKey);
738
739        if ($fileName) {
 
740            if ($isImage) {
 
742                    'altText' => !empty($value['altText']) ? $value['altText'] : '',
 
742                    'altText' => !empty($value['altText']) ? $value['altText'] : '',
 
742                    'altText' => !empty($value['altText']) ? $value['altText'] : '',
743                    'dateUploaded' => Core::getCurrentDate(),
744                    'uploadName' => $fileName,
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
724        if (empty($value['temporaryFileId'])) {
 
729        $submissionContext = $this->request->getContext();
730        if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
734        $temporaryFileManager = new TemporaryFileManager();
735        $temporaryFile = $temporaryFileManager->getFile((int) $value['temporaryFileId'], $userId);
736        $fileNameBase = join('_', ['submission', $submission->getId(), $publication->getId(), $settingName]); // eg - submission_1_1_coverImage
737        $fileName = app()->get('context')->moveTemporaryFile($submissionContext, $temporaryFile, $fileNameBase, $userId, $localeKey);
738
739        if ($fileName) {
 
740            if ($isImage) {
 
742                    'altText' => !empty($value['altText']) ? $value['altText'] : '',
 
742                    'altText' => !empty($value['altText']) ? $value['altText'] : '',
 
742                    'altText' => !empty($value['altText']) ? $value['altText'] : '',
743                    'dateUploaded' => Core::getCurrentDate(),
744                    'uploadName' => $fileName,
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
724        if (empty($value['temporaryFileId'])) {
 
729        $submissionContext = $this->request->getContext();
730        if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
734        $temporaryFileManager = new TemporaryFileManager();
735        $temporaryFile = $temporaryFileManager->getFile((int) $value['temporaryFileId'], $userId);
736        $fileNameBase = join('_', ['submission', $submission->getId(), $publication->getId(), $settingName]); // eg - submission_1_1_coverImage
737        $fileName = app()->get('context')->moveTemporaryFile($submissionContext, $temporaryFile, $fileNameBase, $userId, $localeKey);
738
739        if ($fileName) {
 
740            if ($isImage) {
 
748                    'dateUploaded' => Core::getCurrentDate(),
749                    'uploadName' => $fileName,
688    protected function _saveFileParam(
689        Publication $publication,
690        Submission $submission,
691        $value,
692        string $settingName,
693        int $userId,
694        string $localeKey = '',
695        bool $isImage = false
696    ) {
697        // If the value is null, delete any existing unused file in the system
698        if (is_null($value)) {
 
724        if (empty($value['temporaryFileId'])) {
 
729        $submissionContext = $this->request->getContext();
730        if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
734        $temporaryFileManager = new TemporaryFileManager();
735        $temporaryFile = $temporaryFileManager->getFile((int) $value['temporaryFileId'], $userId);
736        $fileNameBase = join('_', ['submission', $submission->getId(), $publication->getId(), $settingName]); // eg - submission_1_1_coverImage
737        $fileName = app()->get('context')->moveTemporaryFile($submissionContext, $temporaryFile, $fileNameBase, $userId, $localeKey);
738
739        if ($fileName) {
 
754        return null;
755    }
Repository->add
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
301                $submissionContext = app()->get('context')->get($submission->getData('contextId'));
302            }
303
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
 
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
 
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
 
307                    continue;
 
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
301                $submissionContext = app()->get('context')->get($submission->getData('contextId'));
302            }
303
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
 
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
 
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
 
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
301                $submissionContext = app()->get('context')->get($submission->getData('contextId'));
302            }
303
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
 
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
301                $submissionContext = app()->get('context')->get($submission->getData('contextId'));
302            }
303
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
 
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
 
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
 
307                    continue;
 
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
 
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
 
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
301                $submissionContext = app()->get('context')->get($submission->getData('contextId'));
302            }
303
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
 
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
 
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
 
307                    continue;
 
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
301                $submissionContext = app()->get('context')->get($submission->getData('contextId'));
302            }
303
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
 
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
 
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
 
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
301                $submissionContext = app()->get('context')->get($submission->getData('contextId'));
302            }
303
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
 
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
301                $submissionContext = app()->get('context')->get($submission->getData('contextId'));
302            }
303
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
 
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
 
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
 
307                    continue;
 
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
 
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
 
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
 
297            $userId = $this->request->getUser() ? $this->request->getUser()->getId() : null;
298
299            $submissionContext = $this->request->getContext();
300            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
304            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
305            foreach ($supportedLocales as $localeKey) {
 
305            foreach ($supportedLocales as $localeKey) {
306                if (!array_key_exists($localeKey, $publication->getData('coverImage'))) {
307                    continue;
308                }
309                $value[$localeKey] = $this->_saveFileParam($publication, $submission, $publication->getData('coverImage', $localeKey), 'coverImage', $userId, $localeKey, true);
310            }
311
312            $this->edit($publication, ['coverImage' => $value]);
313        }
314
315        Hook::call('Publication::add', [&$publication]);
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
288    public function add(Publication $publication): int
289    {
290        $publication->stampModified();
291        $publicationId = $this->dao->insert($publication);
292        $publication = Repo::publication()->get($publicationId);
293        $submission = Repo::submission()->get($publication->getData('submissionId'));
294
295        // Move uploaded files into place and update the settings
296        if ($publication->getData('coverImage')) {
 
315        Hook::call('Publication::add', [&$publication]);
316
317        // Update a submission's status based on the status of its publications
318        Repo::submission()->updateStatus($submission);
319
320        return $publication->getId();
321    }
Repository->delete
648    public function delete(Publication $publication)
649    {
650        Hook::call('Publication::delete::before', [&$publication]);
651
652        $submission = Repo::submission()->get($publication->getData('submissionId'));
653        $sectionId = $publication->getData(Application::getSectionIdPropName());
654        $section = $sectionId ? Repo::section()->get($sectionId) : null;
 
654        $section = $sectionId ? Repo::section()->get($sectionId) : null;
 
654        $section = $sectionId ? Repo::section()->get($sectionId) : null;
655
656        $this->dao->delete($publication);
657
658        // Update a submission's status based on the status of its remaining publications
659        $submission = Repo::submission()->get($publication->getData('submissionId'));
660        Repo::submission()->updateStatus($submission, null, $section);
661
662        Hook::call('Publication::delete', [&$publication]);
663    }
648    public function delete(Publication $publication)
649    {
650        Hook::call('Publication::delete::before', [&$publication]);
651
652        $submission = Repo::submission()->get($publication->getData('submissionId'));
653        $sectionId = $publication->getData(Application::getSectionIdPropName());
654        $section = $sectionId ? Repo::section()->get($sectionId) : null;
 
654        $section = $sectionId ? Repo::section()->get($sectionId) : null;
 
654        $section = $sectionId ? Repo::section()->get($sectionId) : null;
655
656        $this->dao->delete($publication);
657
658        // Update a submission's status based on the status of its remaining publications
659        $submission = Repo::submission()->get($publication->getData('submissionId'));
660        Repo::submission()->updateStatus($submission, null, $section);
661
662        Hook::call('Publication::delete', [&$publication]);
663    }
Repository->edit
400    public function edit(Publication $publication, array $params): Publication
401    {
402        $submission = Repo::submission()->get($publication->getData('submissionId'));
403        $userId = $this->request->getUser()?->getId();
404
405        // Move uploaded files into place and update the params
406        if (array_key_exists('coverImage', $params)) {
 
407            $submissionContext = $this->request->getContext();
408            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
409                $submissionContext = app()->get('context')->get($submission->getData('contextId'));
410            }
411
412            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
 
412            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
413            foreach ($supportedLocales as $localeKey) {
 
413            foreach ($supportedLocales as $localeKey) {
 
414                if (!array_key_exists($localeKey, $params['coverImage'])) {
 
415                    continue;
 
413            foreach ($supportedLocales as $localeKey) {
 
413            foreach ($supportedLocales as $localeKey) {
414                if (!array_key_exists($localeKey, $params['coverImage'])) {
415                    continue;
416                }
417                $params['coverImage'][$localeKey] = $this->_saveFileParam($publication, $submission, $params['coverImage'][$localeKey], 'coverImage', $userId, $localeKey, true);
418            }
419        }
420
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
 
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
422        $newPublication->stampModified();
423
424        Hook::call('Publication::edit', [&$newPublication, $publication, $params, $this->request]);
425
426        $this->dao->update($newPublication, $publication);
427
428        $newPublication = Repo::publication()->get($newPublication->getId());
429
430        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
431
432        // Log an event when publication data is updated
433        $eventLog = Repo::eventLog()->newDataObject([
434            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
435            'assocId' => $submission->getId(),
436            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UPDATE,
437            'userId' => Validation::loggedInAs() ?? $userId,
438            'message' => 'submission.event.general.metadataUpdated',
439            'isTranslated' => false,
440            'dateLogged' => Core::getCurrentDate(),
441        ]);
442        Repo::eventLog()->add($eventLog);
443
444        return $newPublication;
445    }
400    public function edit(Publication $publication, array $params): Publication
401    {
402        $submission = Repo::submission()->get($publication->getData('submissionId'));
403        $userId = $this->request->getUser()?->getId();
404
405        // Move uploaded files into place and update the params
406        if (array_key_exists('coverImage', $params)) {
 
407            $submissionContext = $this->request->getContext();
408            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
409                $submissionContext = app()->get('context')->get($submission->getData('contextId'));
410            }
411
412            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
 
412            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
413            foreach ($supportedLocales as $localeKey) {
 
413            foreach ($supportedLocales as $localeKey) {
 
414                if (!array_key_exists($localeKey, $params['coverImage'])) {
 
413            foreach ($supportedLocales as $localeKey) {
414                if (!array_key_exists($localeKey, $params['coverImage'])) {
415                    continue;
416                }
417                $params['coverImage'][$localeKey] = $this->_saveFileParam($publication, $submission, $params['coverImage'][$localeKey], 'coverImage', $userId, $localeKey, true);
 
413            foreach ($supportedLocales as $localeKey) {
 
413            foreach ($supportedLocales as $localeKey) {
414                if (!array_key_exists($localeKey, $params['coverImage'])) {
415                    continue;
416                }
417                $params['coverImage'][$localeKey] = $this->_saveFileParam($publication, $submission, $params['coverImage'][$localeKey], 'coverImage', $userId, $localeKey, true);
418            }
419        }
420
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
 
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
422        $newPublication->stampModified();
423
424        Hook::call('Publication::edit', [&$newPublication, $publication, $params, $this->request]);
425
426        $this->dao->update($newPublication, $publication);
427
428        $newPublication = Repo::publication()->get($newPublication->getId());
429
430        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
431
432        // Log an event when publication data is updated
433        $eventLog = Repo::eventLog()->newDataObject([
434            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
435            'assocId' => $submission->getId(),
436            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UPDATE,
437            'userId' => Validation::loggedInAs() ?? $userId,
438            'message' => 'submission.event.general.metadataUpdated',
439            'isTranslated' => false,
440            'dateLogged' => Core::getCurrentDate(),
441        ]);
442        Repo::eventLog()->add($eventLog);
443
444        return $newPublication;
445    }
400    public function edit(Publication $publication, array $params): Publication
401    {
402        $submission = Repo::submission()->get($publication->getData('submissionId'));
403        $userId = $this->request->getUser()?->getId();
404
405        // Move uploaded files into place and update the params
406        if (array_key_exists('coverImage', $params)) {
 
407            $submissionContext = $this->request->getContext();
408            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
409                $submissionContext = app()->get('context')->get($submission->getData('contextId'));
410            }
411
412            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
 
412            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
413            foreach ($supportedLocales as $localeKey) {
 
413            foreach ($supportedLocales as $localeKey) {
 
413            foreach ($supportedLocales as $localeKey) {
414                if (!array_key_exists($localeKey, $params['coverImage'])) {
415                    continue;
416                }
417                $params['coverImage'][$localeKey] = $this->_saveFileParam($publication, $submission, $params['coverImage'][$localeKey], 'coverImage', $userId, $localeKey, true);
418            }
419        }
420
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
 
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
422        $newPublication->stampModified();
423
424        Hook::call('Publication::edit', [&$newPublication, $publication, $params, $this->request]);
425
426        $this->dao->update($newPublication, $publication);
427
428        $newPublication = Repo::publication()->get($newPublication->getId());
429
430        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
431
432        // Log an event when publication data is updated
433        $eventLog = Repo::eventLog()->newDataObject([
434            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
435            'assocId' => $submission->getId(),
436            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UPDATE,
437            'userId' => Validation::loggedInAs() ?? $userId,
438            'message' => 'submission.event.general.metadataUpdated',
439            'isTranslated' => false,
440            'dateLogged' => Core::getCurrentDate(),
441        ]);
442        Repo::eventLog()->add($eventLog);
443
444        return $newPublication;
445    }
400    public function edit(Publication $publication, array $params): Publication
401    {
402        $submission = Repo::submission()->get($publication->getData('submissionId'));
403        $userId = $this->request->getUser()?->getId();
404
405        // Move uploaded files into place and update the params
406        if (array_key_exists('coverImage', $params)) {
 
407            $submissionContext = $this->request->getContext();
408            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
409                $submissionContext = app()->get('context')->get($submission->getData('contextId'));
410            }
411
412            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
 
412            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
413            foreach ($supportedLocales as $localeKey) {
 
413            foreach ($supportedLocales as $localeKey) {
414                if (!array_key_exists($localeKey, $params['coverImage'])) {
415                    continue;
416                }
417                $params['coverImage'][$localeKey] = $this->_saveFileParam($publication, $submission, $params['coverImage'][$localeKey], 'coverImage', $userId, $localeKey, true);
418            }
419        }
420
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
 
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
422        $newPublication->stampModified();
423
424        Hook::call('Publication::edit', [&$newPublication, $publication, $params, $this->request]);
425
426        $this->dao->update($newPublication, $publication);
427
428        $newPublication = Repo::publication()->get($newPublication->getId());
429
430        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
431
432        // Log an event when publication data is updated
433        $eventLog = Repo::eventLog()->newDataObject([
434            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
435            'assocId' => $submission->getId(),
436            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UPDATE,
437            'userId' => Validation::loggedInAs() ?? $userId,
438            'message' => 'submission.event.general.metadataUpdated',
439            'isTranslated' => false,
440            'dateLogged' => Core::getCurrentDate(),
441        ]);
442        Repo::eventLog()->add($eventLog);
443
444        return $newPublication;
445    }
400    public function edit(Publication $publication, array $params): Publication
401    {
402        $submission = Repo::submission()->get($publication->getData('submissionId'));
403        $userId = $this->request->getUser()?->getId();
404
405        // Move uploaded files into place and update the params
406        if (array_key_exists('coverImage', $params)) {
 
407            $submissionContext = $this->request->getContext();
408            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
412            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
413            foreach ($supportedLocales as $localeKey) {
 
413            foreach ($supportedLocales as $localeKey) {
 
414                if (!array_key_exists($localeKey, $params['coverImage'])) {
 
415                    continue;
 
413            foreach ($supportedLocales as $localeKey) {
 
413            foreach ($supportedLocales as $localeKey) {
414                if (!array_key_exists($localeKey, $params['coverImage'])) {
415                    continue;
416                }
417                $params['coverImage'][$localeKey] = $this->_saveFileParam($publication, $submission, $params['coverImage'][$localeKey], 'coverImage', $userId, $localeKey, true);
418            }
419        }
420
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
 
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
422        $newPublication->stampModified();
423
424        Hook::call('Publication::edit', [&$newPublication, $publication, $params, $this->request]);
425
426        $this->dao->update($newPublication, $publication);
427
428        $newPublication = Repo::publication()->get($newPublication->getId());
429
430        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
431
432        // Log an event when publication data is updated
433        $eventLog = Repo::eventLog()->newDataObject([
434            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
435            'assocId' => $submission->getId(),
436            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UPDATE,
437            'userId' => Validation::loggedInAs() ?? $userId,
438            'message' => 'submission.event.general.metadataUpdated',
439            'isTranslated' => false,
440            'dateLogged' => Core::getCurrentDate(),
441        ]);
442        Repo::eventLog()->add($eventLog);
443
444        return $newPublication;
445    }
400    public function edit(Publication $publication, array $params): Publication
401    {
402        $submission = Repo::submission()->get($publication->getData('submissionId'));
403        $userId = $this->request->getUser()?->getId();
404
405        // Move uploaded files into place and update the params
406        if (array_key_exists('coverImage', $params)) {
 
407            $submissionContext = $this->request->getContext();
408            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
412            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
413            foreach ($supportedLocales as $localeKey) {
 
413            foreach ($supportedLocales as $localeKey) {
 
414                if (!array_key_exists($localeKey, $params['coverImage'])) {
 
413            foreach ($supportedLocales as $localeKey) {
414                if (!array_key_exists($localeKey, $params['coverImage'])) {
415                    continue;
416                }
417                $params['coverImage'][$localeKey] = $this->_saveFileParam($publication, $submission, $params['coverImage'][$localeKey], 'coverImage', $userId, $localeKey, true);
 
413            foreach ($supportedLocales as $localeKey) {
 
413            foreach ($supportedLocales as $localeKey) {
414                if (!array_key_exists($localeKey, $params['coverImage'])) {
415                    continue;
416                }
417                $params['coverImage'][$localeKey] = $this->_saveFileParam($publication, $submission, $params['coverImage'][$localeKey], 'coverImage', $userId, $localeKey, true);
418            }
419        }
420
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
 
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
422        $newPublication->stampModified();
423
424        Hook::call('Publication::edit', [&$newPublication, $publication, $params, $this->request]);
425
426        $this->dao->update($newPublication, $publication);
427
428        $newPublication = Repo::publication()->get($newPublication->getId());
429
430        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
431
432        // Log an event when publication data is updated
433        $eventLog = Repo::eventLog()->newDataObject([
434            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
435            'assocId' => $submission->getId(),
436            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UPDATE,
437            'userId' => Validation::loggedInAs() ?? $userId,
438            'message' => 'submission.event.general.metadataUpdated',
439            'isTranslated' => false,
440            'dateLogged' => Core::getCurrentDate(),
441        ]);
442        Repo::eventLog()->add($eventLog);
443
444        return $newPublication;
445    }
400    public function edit(Publication $publication, array $params): Publication
401    {
402        $submission = Repo::submission()->get($publication->getData('submissionId'));
403        $userId = $this->request->getUser()?->getId();
404
405        // Move uploaded files into place and update the params
406        if (array_key_exists('coverImage', $params)) {
 
407            $submissionContext = $this->request->getContext();
408            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
412            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
413            foreach ($supportedLocales as $localeKey) {
 
413            foreach ($supportedLocales as $localeKey) {
 
413            foreach ($supportedLocales as $localeKey) {
414                if (!array_key_exists($localeKey, $params['coverImage'])) {
415                    continue;
416                }
417                $params['coverImage'][$localeKey] = $this->_saveFileParam($publication, $submission, $params['coverImage'][$localeKey], 'coverImage', $userId, $localeKey, true);
418            }
419        }
420
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
 
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
422        $newPublication->stampModified();
423
424        Hook::call('Publication::edit', [&$newPublication, $publication, $params, $this->request]);
425
426        $this->dao->update($newPublication, $publication);
427
428        $newPublication = Repo::publication()->get($newPublication->getId());
429
430        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
431
432        // Log an event when publication data is updated
433        $eventLog = Repo::eventLog()->newDataObject([
434            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
435            'assocId' => $submission->getId(),
436            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UPDATE,
437            'userId' => Validation::loggedInAs() ?? $userId,
438            'message' => 'submission.event.general.metadataUpdated',
439            'isTranslated' => false,
440            'dateLogged' => Core::getCurrentDate(),
441        ]);
442        Repo::eventLog()->add($eventLog);
443
444        return $newPublication;
445    }
400    public function edit(Publication $publication, array $params): Publication
401    {
402        $submission = Repo::submission()->get($publication->getData('submissionId'));
403        $userId = $this->request->getUser()?->getId();
404
405        // Move uploaded files into place and update the params
406        if (array_key_exists('coverImage', $params)) {
 
407            $submissionContext = $this->request->getContext();
408            if ($submissionContext->getId() !== $submission->getData('contextId')) {
 
412            $supportedLocales = $submission->getPublicationLanguages($submissionContext->getSupportedSubmissionMetadataLocales());
413            foreach ($supportedLocales as $localeKey) {
 
413            foreach ($supportedLocales as $localeKey) {
414                if (!array_key_exists($localeKey, $params['coverImage'])) {
415                    continue;
416                }
417                $params['coverImage'][$localeKey] = $this->_saveFileParam($publication, $submission, $params['coverImage'][$localeKey], 'coverImage', $userId, $localeKey, true);
418            }
419        }
420
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
 
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
422        $newPublication->stampModified();
423
424        Hook::call('Publication::edit', [&$newPublication, $publication, $params, $this->request]);
425
426        $this->dao->update($newPublication, $publication);
427
428        $newPublication = Repo::publication()->get($newPublication->getId());
429
430        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
431
432        // Log an event when publication data is updated
433        $eventLog = Repo::eventLog()->newDataObject([
434            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
435            'assocId' => $submission->getId(),
436            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UPDATE,
437            'userId' => Validation::loggedInAs() ?? $userId,
438            'message' => 'submission.event.general.metadataUpdated',
439            'isTranslated' => false,
440            'dateLogged' => Core::getCurrentDate(),
441        ]);
442        Repo::eventLog()->add($eventLog);
443
444        return $newPublication;
445    }
400    public function edit(Publication $publication, array $params): Publication
401    {
402        $submission = Repo::submission()->get($publication->getData('submissionId'));
403        $userId = $this->request->getUser()?->getId();
404
405        // Move uploaded files into place and update the params
406        if (array_key_exists('coverImage', $params)) {
 
421        $newPublication = Repo::publication()->newDataObject(array_merge($publication->_data, $params));
422        $newPublication->stampModified();
423
424        Hook::call('Publication::edit', [&$newPublication, $publication, $params, $this->request]);
425
426        $this->dao->update($newPublication, $publication);
427
428        $newPublication = Repo::publication()->get($newPublication->getId());
429
430        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
431
432        // Log an event when publication data is updated
433        $eventLog = Repo::eventLog()->newDataObject([
434            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
435            'assocId' => $submission->getId(),
436            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UPDATE,
437            'userId' => Validation::loggedInAs() ?? $userId,
438            'message' => 'submission.event.general.metadataUpdated',
439            'isTranslated' => false,
440            'dateLogged' => Core::getCurrentDate(),
441        ]);
442        Repo::eventLog()->add($eventLog);
443
444        return $newPublication;
445    }
Repository->exists
74    public function exists(int $id, ?int $submissionId = null): bool
75    {
76        return $this->dao->exists($id, $submissionId);
77    }
Repository->get
80    public function get(int $id, ?int $submissionId = null): ?Publication
81    {
82        return $this->dao->get($id, $submissionId);
83    }
Repository->getCollector
88        return app(Collector::class);
89    }
Repository->getDateBoundaries
117    public function getDateBoundaries(Collector $query): object
118    {
119        return $this->dao->getDateBoundaries($query);
120    }
Repository->getErrorMessageOverrides
763            'locale.regex' => __('validator.localeKey'),
764            'datePublished.date_format' => __('publication.datePublished.errorFormat'),
765            'urlPath.regex' => __('validator.alpha_dash_period'),
766        ];
767    }
Repository->getIdsBySetting
111    public function getIdsBySetting(string $settingName, $settingValue, int $contextId): Enumerable
112    {
113        return $this->dao->getIdsBySetting($settingName, $settingValue, $contextId);
114    }
Repository->getSchemaMap
98    public function getSchemaMap(Submission $submission, LazyCollection $userGroups, array $genres): maps\Schema
99    {
100        return app('maps')->withExtensions(
101            $this->schemaMap,
102            [
103                'submission' => $submission,
104                'userGroups' => $userGroups,
105                'genres' => $genres,
106            ]
107        );
108    }
Repository->newDataObject
64    public function newDataObject(array $params = []): Publication
65    {
66        $object = $this->dao->newDataObject();
67        if (!empty($params)) {
 
68            $object->setAllData($params);
69        }
70        return $object;
 
70        return $object;
71    }
64    public function newDataObject(array $params = []): Publication
65    {
66        $object = $this->dao->newDataObject();
67        if (!empty($params)) {
 
70        return $object;
71    }
Repository->unpublish
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
 
602            Repo::submission()->updateStatus($submission);
603            $submission = Repo::submission()->get($submission->getId());
604        }
605
606        // Log an event when publication is unpublished. Adjust the message depending
607        // on whether this is the first publication or a subsequent version
608        $msg = 'publication.event.unpublished';
 
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
 
611            $msg = 'publication.event.versionUnpublished';
612        }
613
614        // Mark DOIs stable (if applicable).
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
616            $staleDoiIds = Repo::doi()->getDoisForSubmission($newPublication->getData('submissionId'));
617            Repo::doi()->markStale($staleDoiIds);
618        }
619
620        $eventLog = Repo::eventLog()->newDataObject([
 
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
 
641            ? Application::get()->getRequest()->getContext()
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
 
602            Repo::submission()->updateStatus($submission);
603            $submission = Repo::submission()->get($submission->getId());
604        }
605
606        // Log an event when publication is unpublished. Adjust the message depending
607        // on whether this is the first publication or a subsequent version
608        $msg = 'publication.event.unpublished';
 
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
 
611            $msg = 'publication.event.versionUnpublished';
612        }
613
614        // Mark DOIs stable (if applicable).
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
616            $staleDoiIds = Repo::doi()->getDoisForSubmission($newPublication->getData('submissionId'));
617            Repo::doi()->markStale($staleDoiIds);
618        }
619
620        $eventLog = Repo::eventLog()->newDataObject([
 
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
 
602            Repo::submission()->updateStatus($submission);
603            $submission = Repo::submission()->get($submission->getId());
604        }
605
606        // Log an event when publication is unpublished. Adjust the message depending
607        // on whether this is the first publication or a subsequent version
608        $msg = 'publication.event.unpublished';
 
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
 
611            $msg = 'publication.event.versionUnpublished';
612        }
613
614        // Mark DOIs stable (if applicable).
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
 
641            ? Application::get()->getRequest()->getContext()
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
 
602            Repo::submission()->updateStatus($submission);
603            $submission = Repo::submission()->get($submission->getId());
604        }
605
606        // Log an event when publication is unpublished. Adjust the message depending
607        // on whether this is the first publication or a subsequent version
608        $msg = 'publication.event.unpublished';
 
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
 
611            $msg = 'publication.event.versionUnpublished';
612        }
613
614        // Mark DOIs stable (if applicable).
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
 
602            Repo::submission()->updateStatus($submission);
603            $submission = Repo::submission()->get($submission->getId());
604        }
605
606        // Log an event when publication is unpublished. Adjust the message depending
607        // on whether this is the first publication or a subsequent version
608        $msg = 'publication.event.unpublished';
 
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
 
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
616            $staleDoiIds = Repo::doi()->getDoisForSubmission($newPublication->getData('submissionId'));
617            Repo::doi()->markStale($staleDoiIds);
618        }
619
620        $eventLog = Repo::eventLog()->newDataObject([
 
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
 
641            ? Application::get()->getRequest()->getContext()
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
 
602            Repo::submission()->updateStatus($submission);
603            $submission = Repo::submission()->get($submission->getId());
604        }
605
606        // Log an event when publication is unpublished. Adjust the message depending
607        // on whether this is the first publication or a subsequent version
608        $msg = 'publication.event.unpublished';
 
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
 
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
616            $staleDoiIds = Repo::doi()->getDoisForSubmission($newPublication->getData('submissionId'));
617            Repo::doi()->markStale($staleDoiIds);
618        }
619
620        $eventLog = Repo::eventLog()->newDataObject([
 
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
 
602            Repo::submission()->updateStatus($submission);
603            $submission = Repo::submission()->get($submission->getId());
604        }
605
606        // Log an event when publication is unpublished. Adjust the message depending
607        // on whether this is the first publication or a subsequent version
608        $msg = 'publication.event.unpublished';
 
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
 
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
 
641            ? Application::get()->getRequest()->getContext()
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
 
602            Repo::submission()->updateStatus($submission);
603            $submission = Repo::submission()->get($submission->getId());
604        }
605
606        // Log an event when publication is unpublished. Adjust the message depending
607        // on whether this is the first publication or a subsequent version
608        $msg = 'publication.event.unpublished';
 
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
 
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
 
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
 
611            $msg = 'publication.event.versionUnpublished';
612        }
613
614        // Mark DOIs stable (if applicable).
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
616            $staleDoiIds = Repo::doi()->getDoisForSubmission($newPublication->getData('submissionId'));
617            Repo::doi()->markStale($staleDoiIds);
618        }
619
620        $eventLog = Repo::eventLog()->newDataObject([
 
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
 
641            ? Application::get()->getRequest()->getContext()
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
 
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
 
611            $msg = 'publication.event.versionUnpublished';
612        }
613
614        // Mark DOIs stable (if applicable).
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
616            $staleDoiIds = Repo::doi()->getDoisForSubmission($newPublication->getData('submissionId'));
617            Repo::doi()->markStale($staleDoiIds);
618        }
619
620        $eventLog = Repo::eventLog()->newDataObject([
 
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
 
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
 
611            $msg = 'publication.event.versionUnpublished';
612        }
613
614        // Mark DOIs stable (if applicable).
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
 
641            ? Application::get()->getRequest()->getContext()
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
 
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
 
611            $msg = 'publication.event.versionUnpublished';
612        }
613
614        // Mark DOIs stable (if applicable).
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
 
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
 
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
616            $staleDoiIds = Repo::doi()->getDoisForSubmission($newPublication->getData('submissionId'));
617            Repo::doi()->markStale($staleDoiIds);
618        }
619
620        $eventLog = Repo::eventLog()->newDataObject([
 
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
 
641            ? Application::get()->getRequest()->getContext()
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
 
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
 
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
616            $staleDoiIds = Repo::doi()->getDoisForSubmission($newPublication->getData('submissionId'));
617            Repo::doi()->markStale($staleDoiIds);
618        }
619
620        $eventLog = Repo::eventLog()->newDataObject([
 
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
 
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
 
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
 
641            ? Application::get()->getRequest()->getContext()
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
581    public function unpublish(Publication $publication)
582    {
583        $newPublication = clone $publication;
584        $newPublication->setData('status', Submission::STATUS_QUEUED);
585        $newPublication->stampModified();
586
587        Hook::call(
588            'Publication::unpublish::before',
589            [
590                &$newPublication,
591                $publication
592            ]
593        );
594
595        $this->dao->update($newPublication);
596
597        $newPublication = Repo::publication()->get($newPublication->getId());
598        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
599
600        // Update a submission's status based on the status of its publications
601        if ($newPublication->getData('status') !== $publication->getData('status')) {
 
608        $msg = 'publication.event.unpublished';
609
610        if (count($submission->getData('publications')) > 1) {
 
615        if ($submission->getData('status') !== Submission::STATUS_PUBLISHED) {
 
620        $eventLog = Repo::eventLog()->newDataObject([
621            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
622            'assocId' => $submission->getId(),
623            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_METADATA_UNPUBLISH,
624            'userId' => Validation::loggedInAs() ?? $this->request->getUser()?->getId(),
625            'message' => $msg,
626            'isTranslated' => false,
627            'dateLogged' => Core::getCurrentDate()
628        ]);
629        Repo::eventLog()->add($eventLog);
630
631        Hook::call(
632            'Publication::unpublish',
633            [
634                &$newPublication,
635                $publication,
636                $submission
637            ]
638        );
639
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
 
640        $context = $submission->getData('contextId') === Application::get()->getRequest()->getContext()->getId()
641            ? Application::get()->getRequest()->getContext()
642            : app()->get('context')->get($submission->getData('contextId'));
643
644        event(new PublicationUnpublished($newPublication, $publication, $submission, $context));
645    }
Repository->validate
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
 
171        if (!$submission->getData('submissionProgress')) {
 
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
 
171        if (!$submission->getData('submissionProgress')) {
 
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
 
171        if (!$submission->getData('submissionProgress')) {
 
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
 
171        if (!$submission->getData('submissionProgress')) {
 
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
 
171        if (!$submission->getData('submissionProgress')) {
 
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
 
171        if (!$submission->getData('submissionProgress')) {
 
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
 
171        if (!$submission->getData('submissionProgress')) {
 
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
 
171        if (!$submission->getData('submissionProgress')) {
 
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
 
171        if (!$submission->getData('submissionProgress')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
 
171        if (!$submission->getData('submissionProgress')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
 
171        if (!$submission->getData('submissionProgress')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
 
171        if (!$submission->getData('submissionProgress')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
 
171        if (!$submission->getData('submissionProgress')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
 
171        if (!$submission->getData('submissionProgress')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
 
171        if (!$submission->getData('submissionProgress')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
160            $validator->after(function ($validator) use ($props) {
161                if (!$validator->errors()->get('submissionId')) {
162                    $submission = Repo::submission()->get($props['submissionId']);
163                    if (!$submission) {
164                        $validator->errors()->add('submissionId', __('publication.invalidSubmission'));
165                    }
166                }
167            });
168        }
169
170        // A title must be provided if the submission is not still in progress
171        if (!$submission->getData('submissionProgress')) {
 
171        if (!$submission->getData('submissionProgress')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
171        if (!$submission->getData('submissionProgress')) {
 
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
171        if (!$submission->getData('submissionProgress')) {
 
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
171        if (!$submission->getData('submissionProgress')) {
 
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
171        if (!$submission->getData('submissionProgress')) {
 
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
171        if (!$submission->getData('submissionProgress')) {
 
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
171        if (!$submission->getData('submissionProgress')) {
 
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
171        if (!$submission->getData('submissionProgress')) {
 
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
171        if (!$submission->getData('submissionProgress')) {
 
172            $validator->after(function ($validator) use ($props, $publication, $primaryLocale) {
173                $title = isset($props['title']) && isset($props['title'][$primaryLocale])
174                    ? $props['title'][$primaryLocale]
175                    : $publication?->getData('title', $primaryLocale);
176                if (empty($title)) {
177                    $validator->errors()->add('title.' . $primaryLocale, __('validator.required'));
178                }
179            });
180        }
181
182        // The urlPath must not be used in a publication attached to
183        // any submission other than this publication's submission
184        if (strlen($props['urlPath'] ?? '')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
171        if (!$submission->getData('submissionProgress')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
171        if (!$submission->getData('submissionProgress')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
171        if (!$submission->getData('submissionProgress')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
171        if (!$submission->getData('submissionProgress')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
185            $validator->after(function ($validator) use ($publication, $props) {
186                if (!$validator->errors()->get('urlPath')) {
187                    if (ctype_digit((string) $props['urlPath'])) {
188                        $validator->errors()->add('urlPath', __('publication.urlPath.numberInvalid'));
189                        return;
190                    }
191
192                    // If there is no submissionId the validator will throw it back anyway
193                    if (is_null($publication) && !empty($props['submissionId'])) {
194                        $submission = Repo::submission()->get($props['submissionId']);
195                    } elseif (!is_null($publication)) {
196                        $submission = Repo::submission()->get($publication->getData('submissionId'));
197                    }
198
199                    // If there's no submission we can't validate but the validator should
200                    // fail anyway, so we can return without setting a separate validation
201                    // error.
202                    if (!$submission) {
203                        return;
204                    }
205
206                    if ($this->dao->isDuplicateUrlPath($props['urlPath'], $submission->getId(), $submission->getData('contextId'))) {
207                        $validator->errors()->add('urlPath', __('publication.urlPath.duplicate'));
208                    }
209                }
210            });
211        }
212
213        // If a new file has been uploaded, check that the temporary file exists and
214        // the current user owns it
215        $user = Application::get()->getRequest()->getUser();
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
171        if (!$submission->getData('submissionProgress')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
171        if (!$submission->getData('submissionProgress')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
171        if (!$submission->getData('submissionProgress')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
226            $errors = $this->schemaService->formatValidationErrors($validator->errors());
227        }
228
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
134    public function validate(?Publication $publication, array $props, Submission $submission, Context $context): array
135    {
136        $primaryLocale = $submission->getData('locale');
137        $allowedLocales = $submission->getpublicationLanguages($context->getSupportedSubmissionMetadataLocales());
138
139        $errors = [];
140
141        $validator = ValidatorFactory::make(
142            $props,
143            $this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
144            $this->getErrorMessageOverrides(),
145        );
146
147        ValidatorFactory::required(
148            $validator,
149            $publication,
150            $this->schemaService->getRequiredProps($this->dao->schema),
151            $this->schemaService->getMultilingualProps($this->dao->schema),
152            $allowedLocales,
153            $primaryLocale
154        );
155
156        ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
157
158        // The submissionId must match an existing submission
159        if (isset($props['submissionId'])) {
 
171        if (!$submission->getData('submissionProgress')) {
 
184        if (strlen($props['urlPath'] ?? '')) {
 
215        $user = Application::get()->getRequest()->getUser();
216        ValidatorFactory::temporaryFilesExist(
217            $validator,
218            ['coverImage'],
219            ['coverImage'],
220            $props,
221            $allowedLocales,
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
 
222            $user ? $user->getId() : null
223        );
224
225        if ($validator->fails()) {
 
229        Hook::call('Publication::validate', [&$errors, $publication, $props, $allowedLocales, $primaryLocale]);
230
231        return $errors;
232    }
Repository->validatePublish
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
259            $errors['declined'] = __('publication.required.declined');
260        }
261
262        // Don't allow a publication to be published before passing the review stage
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
264            $errors['reviewStage'] = __('publication.required.reviewStage');
265        }
266
267        // Orcid errors
268        if (OrcidManager::isEnabled()) {
 
268        if (OrcidManager::isEnabled()) {
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
269            $orcidIds = [];
270            foreach ($publication->getData('authors') as $author) {
 
270            foreach ($publication->getData('authors') as $author) {
271                $authorOrcid = $author->getData('orcid');
272                if ($authorOrcid and in_array($authorOrcid, $orcidIds)) {
273                    $errors['hasDuplicateOrcids'] = __('orcid.verify.duplicateOrcidAuthor');
274                } elseif ($authorOrcid && !$author->getData('orcidAccessToken')) {
275                    $errors['hasUnauthenticatedOrcid'] = __('orcid.verify.hasUnauthenticatedOrcid');
276                } else {
277                    $orcidIds[] = $authorOrcid;
278                }
279            }
280        }
281
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
253    public function validatePublish(Publication $publication, Submission $submission, array $allowedLocales, string $primaryLocale): array
254    {
255        $errors = [];
256
257        // Don't allow declined submissions to be published
258        if ($submission->getData('status') === PKPSubmission::STATUS_DECLINED) {
 
263        if ($submission->getData('stageId') <= WORKFLOW_STAGE_ID_EXTERNAL_REVIEW) {
 
268        if (OrcidManager::isEnabled()) {
 
282        Hook::call('Publication::validatePublish', [&$errors, $publication, $submission, $allowedLocales, $primaryLocale]);
283
284        return $errors;
285    }
Repository->version
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
344            $newPublication->setData('doiId', null);
345        }
346        $newId = $this->add($newPublication);
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
351            foreach ($authors as $author) {
 
351            foreach ($authors as $author) {
352                $newAuthor = clone $author;
353                $newAuthor->setData('id', null);
354                $newAuthor->setData('publicationId', $newPublication->getId());
355                $newAuthorId = Repo::author()->add($newAuthor);
356
357                if ($author->getId() === $publication->getData('primaryContactId')) {
358                    $this->edit($newPublication, ['primaryContactId' => $newAuthorId]);
359                }
360            }
361        }
362
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
364            $citationDao = DAORegistry::getDAO('CitationDAO'); /** @var \PKP\citation\CitationDAO $citationDao */
365            $citationDao->importCitations($newPublication->getId(), $newPublication->getData('citationsRaw'));
366        }
367
368        $genreDao = DAORegistry::getDAO('GenreDAO');
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
375            Repo::submissionFile()
376                ->versionSubmissionFile($jatsFile->submissionFile, $newPublication);
377        }
378
379        $newPublication = Repo::publication()->get($newPublication->getId());
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }
331    public function version(Publication $publication): int
332    {
333        $newPublication = clone $publication;
334        $newPublication->setData('id', null);
335        $newPublication->setData('datePublished', null);
336        $newPublication->setData('status', Submission::STATUS_QUEUED);
337        $newPublication->setData('version', $publication->getData('version') + 1);
338        $newPublication->stampModified();
339
340        $request = Application::get()->getRequest();
341        $context = $request->getContext();
342
343        if ($context->getData(Context::SETTING_DOI_VERSIONING)) {
 
346        $newId = $this->add($newPublication);
347        $newPublication = Repo::publication()->get($newId);
348
349        $authors = $publication->getData('authors');
350        if (!empty($authors)) {
 
363        if (!empty($newPublication->getData('citationsRaw'))) {
 
368        $genreDao = DAORegistry::getDAO('GenreDAO');
369        $genres = $genreDao->getEnabledByContextId($context->getId());
370
371        $jatsFile = Repo::jats()
372            ->getJatsFile($publication->getId(), null, $genres->toArray());
373
374        if (!$jatsFile->isDefaultContent) {
 
379        $newPublication = Repo::publication()->get($newPublication->getId());
380
381        Hook::call('Publication::version', [&$newPublication, $publication]);
382
383        $submission = Repo::submission()->get($newPublication->getData('submissionId'));
384
385        $eventLog = Repo::eventLog()->newDataObject([
386            'assocType' => PKPApplication::ASSOC_TYPE_SUBMISSION,
387            'assocId' => $submission->getId(),
388            'eventType' => PKPSubmissionEventLogEntry::SUBMISSION_LOG_CREATE_VERSION,
389            'userId' => Validation::loggedInAs() ?? $request->getUser()?->getId(),
390            'message' => 'publication.event.versionCreated',
391            'isTranslated' => false,
392            'dateLogged' => Core::getCurrentDate(),
393        ]);
394        Repo::eventLog()->add($eventLog);
395
396        return $newPublication->getId();
397    }